package hr.fer.zemris.rznu.model.dao.impl;

import hr.fer.zemris.rznu.model.authorization.Role;
import hr.fer.zemris.rznu.model.authorization.Role.RoleType;
import hr.fer.zemris.rznu.model.authorization.UserInRole;
import hr.fer.zemris.rznu.model.dao.interfaces.IGeneralDAO;
import hr.fer.zemris.rznu.model.user.User;

import java.util.Collection;
import java.util.LinkedList;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author Dajan
 *
 */
public class GeneralDAO implements IGeneralDAO{

	private EntityManagerFactory emf;
	protected EntityManager em;

	private static final Log log = LogFactory.getLog(GeneralDAO.class);

	public GeneralDAO(EntityManagerFactory emf) {
		this.emf = emf;
		createEntityManager();
	}
	
	public void createEntityManager() {
		if(this.em==null){
			this.em = this.emf.createEntityManager();
			log.info("em created");
		}
	}

	@Override
	public User getUserByUserName(String userName) {
		return (User) em.createNamedQuery("userByUserName").setParameter("username", userName).getSingleResult();
		
	}
	
	public Collection<User> getAllUsers() {
		return (Collection<User>)em.createNamedQuery("allUsers").getResultList();
	}
	
	/**
	 * Get user by id from database.
	 * 
	 * @param id
	 *            User id.
	 * @param session
	 *            Entity Manager session.
	 * @return User.
	 */
	public User getUserById(Integer id) {
		return (User) em.createNamedQuery("userById").setParameter(1, 1)
				.getSingleResult();
	}

	/**
	 * Save entity object to database.
	 * 
	 * @param obj
	 *            Entity object.
	 */
	public void save(Object obj) {
		em.persist(obj);
	}

	/**
	 * Update entity object in database.
	 * 
	 * @param obj
	 *            Entity object.
	 */
	public void update(Object obj) {
		em.merge(obj);
	}

	/**
	 * Delete entity object from database.
	 * 
	 * @param obj
	 *            Entity object.
	 */
	public void delete(Object obj) {
		em.remove(obj);
	}

	public EntityManager getEntityManager() {
		return this.em;
	}

	public void close() {
		this.em.close();
		this.em=null;
		log.info("em closed");
	}


	

	
	public Role getRoleByName(RoleType roleType) {
		Role role;
		try{
			role = (Role)em.createNamedQuery("roleByName")
						   .setParameter(1,roleType.name())
						   .getSingleResult();
		}catch(NoResultException e){
			role=null;
		}
		return role;
	}
	
	public Collection<User> getAdminUsers() {
		Role adminRole = getRoleByName(RoleType.ADMIN);
		System.out.println(adminRole);
		
		Collection<User> users = new LinkedList<User>();
		
		System.out.println(adminRole.getUsersInRole());
		
		for(UserInRole uir : adminRole.getUsersInRole()){
			users.add(uir.getUser());
		}
		return users;
	}
}
